<template>
  <div class="map-3d" ref="map3dContainer">
    <!-- 3D场景容器 -->
    <div class="scene-container" ref="sceneContainer"></div>
    
    <!-- 3D控制面板 -->
    <div class="controls-3d">
      <div class="view-controls">
        <button class="control-btn" @click="resetView" title="重置视角">
          <svg viewBox="0 0 24 24">
            <path d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M18,11H13L14.5,9.5L12.5,7.5L11,9H6V11H11L9.5,12.5L11.5,14.5L13,13H18V11Z" fill="currentColor"/>
          </svg>
        </button>
        <button class="control-btn" @click="toggleAutoRotate" :class="{ active: autoRotate }" title="自动旋转">
          <svg viewBox="0 0 24 24">
            <path d="M12,6V9L16,5L12,1V4A8,8 0 0,0 4,12C4,13.57 4.46,15.03 5.24,16.26L6.7,14.8C6.25,13.97 6,13 6,12A6,6 0 0,1 12,6M18.76,7.74L17.3,9.2C17.74,10.03 18,11 18,12A6,6 0 0,1 12,18V15L8,19L12,23V20A8,8 0 0,0 20,12C20,10.43 19.54,8.97 18.76,7.74Z" fill="currentColor"/>
          </svg>
        </button>
        <button class="control-btn" @click="switchView('overview')" :class="{ active: currentView === 'overview' }" title="鸟瞰视角">
          <svg viewBox="0 0 24 24">
            <path d="M12,2L13.09,8.26L17,7L14.94,9.06L19,12L14.94,14.94L17,17L13.09,15.74L12,22L10.91,15.74L7,17L9.06,14.94L5,12L9.06,9.06L7,7L10.91,8.26L12,2Z" fill="currentColor"/>
          </svg>
        </button>
        <button class="control-btn" @click="switchView('island')" :class="{ active: currentView === 'island' }" title="岛屿视角">
          <svg viewBox="0 0 24 24">
            <path d="M5.39,19L6.43,18.91C6.15,18.54 6,18.11 6,17.67A1.67,1.67 0 0,1 7.67,16A1.67,1.67 0 0,1 9.33,17.67C9.33,18.11 9.18,18.54 8.9,18.91L9.94,19C10.31,18.54 10.5,18 10.5,17.33A2.5,2.5 0 0,0 8,14.83A2.5,2.5 0 0,0 5.5,17.33C5.5,18 5.69,18.54 6.06,19M12,2L13.09,8.26L17,7L14.94,9.06L19,12L14.94,14.94L17,17L13.09,15.74L12,22L10.91,15.74L7,17L9.06,14.94L5,12L9.06,9.06L7,7L10.91,8.26L12,2Z" fill="currentColor"/>
          </svg>
        </button>
      </div>
      
      <div class="info-panel">
        <div class="coordinate-display">
          <span>视角高度: {{ cameraHeight.toFixed(1) }}m</span>
          <span>缩放级别: {{ zoomLevel.toFixed(1) }}x</span>
        </div>
      </div>
    </div>

    <!-- POI信息悬浮层 -->
    <div v-if="hoveredPoi" class="poi-tooltip" :style="tooltipStyle">
      <div class="tooltip-header">
        <span class="poi-name">{{ hoveredPoi.name }}</span>
        <span class="poi-type">{{ getPoiTypeLabel(hoveredPoi.type) }}</span>
      </div>
      <div class="tooltip-content">
        <div v-if="hoveredPoi.type === 'scenic'" class="scenic-info">
          <p>游客数量: {{ hoveredPoi.data.currentVisitors }}/{{ hoveredPoi.data.capacity }}</p>
          <p>温度: {{ hoveredPoi.data.temperature }}°C</p>
        </div>
        <div v-else-if="hoveredPoi.type === 'monitor'" class="monitor-info">
          <p>设备: {{ hoveredPoi.data.deviceType }}</p>
          <p>分辨率: {{ hoveredPoi.data.resolution }}</p>
        </div>
        <div v-else-if="hoveredPoi.type === 'entrance'" class="entrance-info">
          <p>日通行量: {{ hoveredPoi.data.dailyTraffic }}</p>
          <p>当前流量: {{ hoveredPoi.data.currentFlow }}</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue'
import * as THREE from 'three'
import { poiData, terrainHeights, poiTypes } from './poiData.js'

// Props
const props = defineProps({
  filteredPois: {
    type: Array,
    default: () => poiData
  },
  selectedPoiType: {
    type: String,
    default: 'all'
  }
})

// Emits
const emit = defineEmits(['poiHover', 'poiClick'])

// 响应式数据
const map3dContainer = ref(null)
const sceneContainer = ref(null)
const autoRotate = ref(false)
const currentView = ref('overview')
const cameraHeight = ref(30)
const zoomLevel = ref(1)
const hoveredPoi = ref(null)
const tooltipStyle = ref({})

// Three.js 对象
let scene, camera, renderer, controls
let raycaster, mouse, animationId
let lakeGroup, terrainGroup, poiGroup
let lakeWater, mountains

// 初始化3D场景
const init3DScene = async () => {
  if (!sceneContainer.value) return

  try {
    // 创建场景
    scene = new THREE.Scene()
    scene.background = new THREE.Color(0x87CEEB) // 天空蓝色
    scene.fog = new THREE.Fog(0x87CEEB, 80, 200)

    // 创建相机
    const width = sceneContainer.value.clientWidth
    const height = sceneContainer.value.clientHeight
    camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 1000)
    camera.position.set(50, 40, 60)

    // 创建渲染器
    renderer = new THREE.WebGLRenderer({ 
      antialias: true,
      alpha: true
    })
    renderer.setSize(width, height)
    renderer.shadowMap.enabled = true
    renderer.shadowMap.type = THREE.PCFSoftShadowMap
    renderer.setClearColor(0x87CEEB, 0.9)
    sceneContainer.value.appendChild(renderer.domElement)

    // 添加轨道控制器
    const OrbitControls = (await import('three/examples/jsm/controls/OrbitControls.js')).OrbitControls
    controls = new OrbitControls(camera, renderer.domElement)
    controls.enableDamping = true
    controls.dampingFactor = 0.05
    controls.target.set(50, 0, 0) // 聚焦在观音湖中心
    controls.maxDistance = 200
    controls.minDistance = 10
    controls.maxPolarAngle = Math.PI * 0.8

    // 添加光照
    setupLighting()

    // 创建地形
    createTerrain()

    // 创建湖面
    createLake()

    // 创建POI标记
    createPoiMarkers()

    // 添加射线投射器用于交互
    raycaster = new THREE.Raycaster()
    mouse = new THREE.Vector2()

    // 添加事件监听
    renderer.domElement.addEventListener('mousemove', onMouseMove)
    renderer.domElement.addEventListener('click', onMouseClick)
    window.addEventListener('resize', onWindowResize)

    // 开始渲染循环
    animate()

  } catch (error) {
    console.error('3D场景初始化失败:', error)
  }
}

// 设置光照
const setupLighting = () => {
  // 环境光
  const ambientLight = new THREE.AmbientLight(0x404040, 0.6)
  scene.add(ambientLight)

  // 主光源（太阳光）
  const directionalLight = new THREE.DirectionalLight(0xffffff, 1.2)
  directionalLight.position.set(100, 100, 50)
  directionalLight.castShadow = true
  directionalLight.shadow.mapSize.width = 2048
  directionalLight.shadow.mapSize.height = 2048
  directionalLight.shadow.camera.near = 0.5
  directionalLight.shadow.camera.far = 500
  directionalLight.shadow.camera.left = -100
  directionalLight.shadow.camera.right = 100
  directionalLight.shadow.camera.top = 100
  directionalLight.shadow.camera.bottom = -100
  scene.add(directionalLight)

  // 补充光源
  const fillLight = new THREE.DirectionalLight(0x87CEEB, 0.3)
  fillLight.position.set(-50, 30, -50)
  scene.add(fillLight)
}

// 创建地形
const createTerrain = () => {
  terrainGroup = new THREE.Group()

  // 创建基础地面
  const groundGeometry = new THREE.PlaneGeometry(160, 80)
  const groundMaterial = new THREE.MeshLambertMaterial({ 
    color: 0x4a7c59,
    transparent: true,
    opacity: 0.8
  })
  const ground = new THREE.Mesh(groundGeometry, groundMaterial)
  ground.rotation.x = -Math.PI / 2
  ground.position.y = -1
  ground.receiveShadow = true
  terrainGroup.add(ground)

  // 创建山体地形
  createMountains()

  scene.add(terrainGroup)
}

// 创建山体
const createMountains = () => {
  // 灵泉寺山体（东部）
  const lingquanGeometry = new THREE.ConeGeometry(8, 15, 8)
  const mountainMaterial = new THREE.MeshLambertMaterial({ color: 0x3d5a47 })
  const lingquanMountain = new THREE.Mesh(lingquanGeometry, mountainMaterial)
  lingquanMountain.position.set(75, 7.5, 15)
  lingquanMountain.castShadow = true
  terrainGroup.add(lingquanMountain)

  // 广德寺山体（西部）
  const guangdeGeometry = new THREE.ConeGeometry(6, 18, 8)
  const guangdeMountain = new THREE.Mesh(guangdeGeometry, mountainMaterial)
  guangdeMountain.position.set(25, 9, 20)
  guangdeMountain.castShadow = true
  terrainGroup.add(guangdeMountain)

  // 创建更多小山丘
  for (let i = 0; i < 8; i++) {
    const hillGeometry = new THREE.ConeGeometry(
      Math.random() * 3 + 1, 
      Math.random() * 6 + 2, 
      6
    )
    const hill = new THREE.Mesh(hillGeometry, mountainMaterial)
    hill.position.set(
      Math.random() * 140 + 10,
      (Math.random() * 6 + 2) / 2,
      Math.random() * 60 - 30
    )
    hill.castShadow = true
    terrainGroup.add(hill)
  }
}

// 创建湖面
const createLake = () => {
  lakeGroup = new THREE.Group()

  // 基于真实观音湖轮廓创建湖面形状（东西向狭长型）
  const lakeShape = new THREE.Shape()
  
  // 观音湖真实轮廓点（简化版）
  lakeShape.moveTo(10, 15)   // 西端起始点
  lakeShape.quadraticCurveTo(25, 10, 40, 12)  // 西段弯曲
  lakeShape.quadraticCurveTo(60, 8, 80, 10)   // 中西段
  lakeShape.quadraticCurveTo(100, 9, 120, 12) // 中东段
  lakeShape.quadraticCurveTo(135, 15, 145, 20) // 东段弯曲
  lakeShape.lineTo(142, 25)  // 东端转折
  lakeShape.quadraticCurveTo(130, 30, 115, 28) // 南岸东段
  lakeShape.quadraticCurveTo(95, 32, 75, 30)   // 南岸中段
  lakeShape.quadraticCurveTo(55, 32, 35, 28)   // 南岸西段
  lakeShape.quadraticCurveTo(20, 25, 15, 22)   // 西端南岸
  lakeShape.lineTo(10, 15)   // 回到起始点

  const lakeGeometry = new THREE.ShapeGeometry(lakeShape)
  const lakeMaterial = new THREE.MeshPhongMaterial({ 
    color: 0x1976d2,
    transparent: true,
    opacity: 0.75,
    shininess: 100,
    side: THREE.DoubleSide
  })
  
  lakeWater = new THREE.Mesh(lakeGeometry, lakeMaterial)
  lakeWater.rotation.x = -Math.PI / 2
  lakeWater.position.set(0, 0.1, 0)
  lakeWater.receiveShadow = true
  lakeGroup.add(lakeWater)

  // 创建三圣岛（湖心最大岛屿）
  const sanshengGeometry = new THREE.CylinderGeometry(5, 6, 3, 12)
  const islandMaterial = new THREE.MeshLambertMaterial({ color: 0x2e5c2e })
  const sanshengIsland = new THREE.Mesh(sanshengGeometry, islandMaterial)
  sanshengIsland.position.set(80, 1.5, 16) // 湖中心偏东
  sanshengIsland.castShadow = true
  lakeGroup.add(sanshengIsland)

  // 创建观音圣像（三圣岛上）
  const statueGeometry = new THREE.CylinderGeometry(0.8, 1.2, 8, 8)
  const statueMaterial = new THREE.MeshLambertMaterial({ color: 0xf5deb3 })
  const observerStatue = new THREE.Mesh(statueGeometry, statueMaterial)
  observerStatue.position.set(80, 5.5, 16)
  observerStatue.castShadow = true
  lakeGroup.add(observerStatue)

  // 创建莲花岛等小岛屿
  const lianhuaGeometry = new THREE.CylinderGeometry(2.5, 3, 2, 8)
  const lianhuaIsland = new THREE.Mesh(lianhuaGeometry, islandMaterial)
  lianhuaIsland.position.set(110, 1, 20)
  lianhuaIsland.castShadow = true
  lakeGroup.add(lianhuaIsland)

  // 另一个小岛
  const smallIslandGeometry = new THREE.CylinderGeometry(1.5, 2, 1.5, 6)
  const smallIsland = new THREE.Mesh(smallIslandGeometry, islandMaterial)
  smallIsland.position.set(50, 0.75, 12)
  smallIsland.castShadow = true
  lakeGroup.add(smallIsland)

  // 创建观音湖大桥
  const bridgeGeometry = new THREE.BoxGeometry(60, 1.5, 3)
  const bridgeMaterial = new THREE.MeshLambertMaterial({ color: 0x666666 })
  const bridge = new THREE.Mesh(bridgeGeometry, bridgeMaterial)
  bridge.position.set(75, 3, 5)
  bridge.rotation.y = Math.PI / 8 // 略微倾斜角度
  bridge.castShadow = true
  lakeGroup.add(bridge)

  // 添加桥墩
  for (let i = 0; i < 3; i++) {
    const pillarGeometry = new THREE.CylinderGeometry(0.8, 1, 8, 8)
    const pillarMaterial = new THREE.MeshLambertMaterial({ color: 0x555555 })
    const pillar = new THREE.Mesh(pillarGeometry, pillarMaterial)
    pillar.position.set(60 + i * 15, 4, 3 + i * 1.5)
    pillar.castShadow = true
    lakeGroup.add(pillar)
  }

  scene.add(lakeGroup)
}

// 创建POI标记
const createPoiMarkers = () => {
  poiGroup = new THREE.Group()
  
  props.filteredPois.forEach(poi => {
    createPoiMarker(poi)
  })
  
  scene.add(poiGroup)
}

// 创建单个POI标记
const createPoiMarker = (poi) => {
  const markerGroup = new THREE.Group()
  
  // 获取POI类型配置
  const typeConfig = poiTypes[poi.type] || poiTypes.scenic
  const color = new THREE.Color(typeConfig.color)
  
  // 创建标记几何体
  let markerGeometry
  switch (poi.type) {
    case 'scenic':
      markerGeometry = new THREE.SphereGeometry(1.5, 8, 6)
      break
    case 'monitor':
      markerGeometry = new THREE.BoxGeometry(1, 2, 1)
      break
    case 'entrance':
      markerGeometry = new THREE.CylinderGeometry(1, 1, 2, 6)
      break
    default:
      markerGeometry = new THREE.ConeGeometry(1, 2, 6)
  }
  
  const markerMaterial = new THREE.MeshLambertMaterial({ 
    color: color,
    emissive: color.clone().multiplyScalar(0.1)
  })
  
  const marker = new THREE.Mesh(markerGeometry, markerMaterial)
  marker.position.set(poi.position.x, poi.position.y + 1, poi.position.z)
  marker.castShadow = true
  marker.userData = { poi }
  
  // 添加发光效果
  if (poi.isAlert) {
    const glowGeometry = new THREE.SphereGeometry(2, 8, 6)
    const glowMaterial = new THREE.MeshBasicMaterial({
      color: 0xff0000,
      transparent: true,
      opacity: 0.3
    })
    const glow = new THREE.Mesh(glowGeometry, glowMaterial)
    glow.position.copy(marker.position)
    markerGroup.add(glow)
  }
  
  markerGroup.add(marker)
  poiGroup.add(markerGroup)
}

// 鼠标移动事件
const onMouseMove = (event) => {
  const rect = renderer.domElement.getBoundingClientRect()
  mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1
  mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1
  
  // 射线检测
  raycaster.setFromCamera(mouse, camera)
  const intersects = raycaster.intersectObjects(poiGroup.children, true)
  
  if (intersects.length > 0) {
    const intersectedObject = intersects[0].object
    if (intersectedObject.userData.poi) {
      hoveredPoi.value = intersectedObject.userData.poi
      tooltipStyle.value = {
        left: `${event.clientX - rect.left + 10}px`,
        top: `${event.clientY - rect.top - 10}px`,
        position: 'absolute'
      }
      emit('poiHover', intersectedObject.userData.poi)
    }
  } else {
    hoveredPoi.value = null
  }
}

// 鼠标点击事件
const onMouseClick = (event) => {
  if (hoveredPoi.value) {
    emit('poiClick', hoveredPoi.value)
  }
}

// 窗口大小改变
const onWindowResize = () => {
  if (!camera || !renderer) return
  
  const width = sceneContainer.value.clientWidth
  const height = sceneContainer.value.clientHeight
  
  camera.aspect = width / height
  camera.updateProjectionMatrix()
  renderer.setSize(width, height)
}

// 动画循环
const animate = () => {
  animationId = requestAnimationFrame(animate)
  
  if (controls) {
    controls.update()
  }
  
  // 更新摄像机信息
  cameraHeight.value = camera.position.y
  zoomLevel.value = 100 / camera.position.distanceTo(controls.target)
  
  // 湖面动画
  if (lakeWater) {
    lakeWater.material.opacity = 0.7 + Math.sin(Date.now() * 0.001) * 0.1
  }
  
  // 旋转动画
  if (autoRotate.value && controls) {
    controls.autoRotate = true
    controls.autoRotateSpeed = 1
  } else if (controls) {
    controls.autoRotate = false
  }
  
  renderer.render(scene, camera)
}

// 重置视角
const resetView = () => {
  if (camera && controls) {
    camera.position.set(50, 40, 60)
    controls.target.set(50, 0, 0)
    controls.update()
  }
}

// 切换自动旋转
const toggleAutoRotate = () => {
  autoRotate.value = !autoRotate.value
}

// 切换视角
const switchView = (viewType) => {
  currentView.value = viewType
  
  if (!camera || !controls) return
  
  switch (viewType) {
    case 'overview':
      camera.position.set(50, 60, 80)
      controls.target.set(50, 0, 0)
      break
    case 'island':
      camera.position.set(50, 20, 20)
      controls.target.set(50, 2, 0)
      break
  }
  controls.update()
}

// 获取POI类型标签
const getPoiTypeLabel = (type) => {
  return poiTypes[type]?.label || '未知类型'
}

// 监听POI过滤变化
watch(() => props.filteredPois, (newPois) => {
  if (poiGroup) {
    // 清除现有标记
    while (poiGroup.children.length > 0) {
      poiGroup.remove(poiGroup.children[0])
    }
    
    // 重新创建标记
    newPois.forEach(poi => {
      createPoiMarker(poi)
    })
  }
}, { deep: true })

// 生命周期
onMounted(() => {
  setTimeout(() => {
    init3DScene()
  }, 100)
})

onUnmounted(() => {
  if (animationId) {
    cancelAnimationFrame(animationId)
  }
  
  if (renderer) {
    renderer.domElement.removeEventListener('mousemove', onMouseMove)
    renderer.domElement.removeEventListener('click', onMouseClick)
    window.removeEventListener('resize', onWindowResize)
    
    if (sceneContainer.value && renderer.domElement) {
      sceneContainer.value.removeChild(renderer.domElement)
    }
    renderer.dispose()
  }
})
</script>

<style scoped>
.map-3d {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
}

.scene-container {
  width: 100%;
  height: 100%;
}

.controls-3d {
  position: absolute;
  top: 20px;
  right: 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  z-index: 10;
}

.view-controls {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  border-radius: 12px;
  padding: 12px;
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.control-btn {
  width: 40px;
  height: 40px;
  border: none;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.1);
  color: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
  backdrop-filter: blur(5px);
}

.control-btn:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: scale(1.05);
}

.control-btn.active {
  background: rgba(74, 144, 226, 0.6);
  box-shadow: 0 0 15px rgba(74, 144, 226, 0.4);
}

.control-btn svg {
  width: 20px;
  height: 20px;
}

.info-panel {
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  border-radius: 12px;
  padding: 12px;
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.coordinate-display {
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: white;
  font-size: 12px;
}

.poi-tooltip {
  background: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 12px;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  max-width: 250px;
  z-index: 1000;
  pointer-events: none;
}

.tooltip-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
  padding-bottom: 6px;
}

.poi-name {
  font-weight: bold;
  font-size: 14px;
}

.poi-type {
  font-size: 12px;
  color: #4fc3f7;
}

.tooltip-content {
  font-size: 12px;
  line-height: 1.4;
}

.tooltip-content p {
  margin: 4px 0;
}
</style> 